/*===========================================================================
  Copyright (C) 2014 by the Okapi Framework contributors
-----------------------------------------------------------------------------
  This library is free software; you can redistribute it and/or modify it 
  under the terms of the GNU Lesser General Public License as published by 
  the Free Software Foundation; either version 2.1 of the License, or (at 
  your option) any later version.

  This library is distributed in the hope that it will be useful, but 
  WITHOUT ANY WARRANTY; without even the implied warranty of 
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 
  General Public License for more details.

  You should have received a copy of the GNU Lesser General Public License 
  along with this library; if not, write to the Free Software Foundation, 
  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

  See also the full LGPL text here: http://www.gnu.org/copyleft/lesser.html
===========================================================================*/

package org.example;

import java.io.File;
import java.util.List;

import net.sf.okapi.lib.xliff2.core.Fragment;
import net.sf.okapi.lib.xliff2.core.Note;
import net.sf.okapi.lib.xliff2.core.Part.GetTarget;
import net.sf.okapi.lib.xliff2.core.Segment;
import net.sf.okapi.lib.xliff2.core.Unit;
import net.sf.okapi.lib.xliff2.document.XLIFFDocument;
import net.sf.okapi.lib.xliff2.reader.Event;
import net.sf.okapi.lib.xliff2.reader.XLIFFReader;
import net.sf.okapi.lib.xliff2.validation.Issue;
import net.sf.okapi.lib.xliff2.validation.Rule;
import net.sf.okapi.lib.xliff2.validation.Validation;
import net.sf.okapi.lib.xliff2.writer.XLIFFWriter;

public class Main {
	
	public static void main (String[] args) {

		// Create a new XLIFF document from scratch
		System.out.println("=== Create a new XLIFF document");
		try ( XLIFFWriter writer = new XLIFFWriter() ) {
			// Create a new document (with English as the source language)
			writer.create(new File("myDocument1.xlf"), "en");
			// Create a unit
			Unit unit = new Unit("u1");
			// Add a segment and get the source content
			Fragment content = unit.appendSegment().getSource();
			content.append("Hello ");
			content.openCodeSpan("1", "<B>");
			content.append("World");
			content.closeCodeSpan("1", "</B>");
			content.append("!");
			// Write the unit
			// Enclosing elements are created with defaults if you don't write
			// them explicitly
			writer.writeUnit(unit);
			// If you forget to write the ends of elements, close() will do it.
			// And if you use a try-with-resources like here it will call close() for you.
		}
		System.out.println("The new document myDocument1.xlf was created.\n");
		
		// Read the document we have created
		System.out.println("=== Read the XLIFF document just created");
		try ( XLIFFReader reader = new XLIFFReader()) {
			reader.open(new File("myDocument1.xlf"));
			// Loop through the reader events
			while (reader.hasNext()) {
				Event event = reader.next();
				// Do something: here print the source content
				if ( event.isUnit() ) {
					Unit unit = event.getUnit();
					for (Segment segment : unit.getSegments()) {
						System.out.println(segment.getSource().getPlainText());
					}
				}
			}
		}
		System.out.println("The document was read.\n");

		File myDocument2 = new File("myDocument2.xlf");
		
		// Now read the document, make a modification (add a note) and re-write it
		System.out.println("=== Read the document, add a note to the units, re-write the result");
		try (
			XLIFFReader reader = new XLIFFReader();
			XLIFFWriter writer = new XLIFFWriter()
		) {
			reader.open(new File("myDocument1.xlf"));
			writer.create(myDocument2, null);
			// Loop through the events
			while (reader.hasNext()) {
				Event event = reader.next();
				// Do whatever modifications you need
				// Here we add a note to any unit we find
				if ( event.isUnit() ) {
					Unit unit = event.getUnit();
					System.out.println(String.format("Adding a note to unit id='%s'", unit.getId()));
					unit.getNotes().add(new Note("My note!"));
				}
				// Then re-write each event
				writer.writeEvent(event);
			}
			// Call writer.close() and reader.close() here
			// if you don't use a try-with-resources like this example.
		}
		System.out.println("The document was read, modified and re-written in myDocument2.xlf.\n");

		// Use the XLIFFDocument class to perform tasks on non-sequential objects 
		System.out.println("=== Read the document into a single object and add a target");
		XLIFFDocument doc = new XLIFFDocument();
		// Load the document
		doc.load(myDocument2);
		// Get the first unit of the first file
		Unit unit = doc.getUnitNode("f1", "u1").get();
		Segment seg = unit.getSegment(0);
		Fragment frag = seg.getTarget(GetTarget.CREATE_EMPTY);
		frag.append("some translation");
		// Also add the target info
		doc.getStartXliffData().setTargetLanguage("fr");
		// Save the document
		doc.save();
		System.out.println("The document was modified and re-written in myDocument2.xlf.\n");
		
		// Make sure we have still a valid document
		XLIFFReader.validate(myDocument2);

		// Use the XLIFFDocument class to perform tasks on non-sequential objects 
		System.out.println("=== Read the document again and use a Validation rule on the unit");
		doc = new XLIFFDocument();
		// Load the document
		doc.load(myDocument2);
		unit = doc.getUnitNode("f1", "u1").get();
		// Create a validation rule and add it
		Validation validation = unit.getValidation();
		validation.add(new Rule("endsWith", ":"));
		validation.prepare();
		// Verify if the rules are respected
		List<Issue> issues = validation.processRules(unit, "f1");
		if ( issues == null ) {
		   System.out.println("No rule found.");
		}
		else if ( issues.isEmpty() ) {
		   System.out.println("No validation rule error found.");
		}
		else {
		   System.out.println("One or more validation errors found:");
		   for ( Issue issue : issues ) {
			   System.out.println("-- "+issue.getText());
		   }
		}
	}

}
